﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WaterRegimenMonitor.Web.Models.Account;
using Telerik.Web.Mvc;
using WaterRegimenMonitor.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data;
using WaterRegimenMonitor.Web.Code;
using System.Text;
using WaterRegimenMonitor.Web.DataModel;
using System.ComponentModel;
using WaterRegimenMonitor.Web.Models;

namespace WaterRegimenMonitor.Web.Domain
{
    public class UserHelper
    {
        /// <summary>
        /// 根据指定的登录名获得用户信息。
        /// </summary>
        /// <param name="loginName">用户的登录名。</param>
        /// <returns>根据指定的登录名获得的用户信息。</returns>
        /// <remarks></remarks>
        public static User GetUserByLoginName(string loginName)
        {
            //获得数据库对象
            Database db = DatabaseFactory.CreateDatabase();

            //创建命令
            SqlCommand command = new SqlCommand
            {
                CommandText = "SELECT * FROM  [User] WHERE [LoginName] = @LoginName",
                CommandType = System.Data.CommandType.Text
            };

            //创建参数
            SqlParameter paramUserID = new SqlParameter()
            {
                SqlDbType = System.Data.SqlDbType.NVarChar,
                ParameterName = "@LoginName",
                Value = loginName
            };

            //添加参数
            command.Parameters.Add(paramUserID);

            //查询用户信息
            DataSet ds = db.ExecuteDataSet(command);

            //判断用户信息是否存在
            if (ds.Tables.Count == 0 || ds.Tables[0].Rows.Count == 0)
            {
                return null;
            }

            //获得数据行
            DataRow row = ds.Tables[0].Rows[0];

            //创建用户实体
            User entity = new User()
            {
                UserID = DatabaseHelper.SafeGetValue<Guid>(row, "UserID", Guid.Empty),
                UserName = DatabaseHelper.SafeGetValue<string>(row, "UserName", string.Empty),
                Memo = DatabaseHelper.SafeGetValue<string>(row, "Memo", string.Empty),
                IsEnabled = DatabaseHelper.SafeGetValue<bool>(row, "IsEnabled", false),
                IsBuildin = DatabaseHelper.SafeGetValue<bool>(row, "IsBuildin", false),
                IsLocked = DatabaseHelper.SafeGetValue<bool>(row, "IsLocked", false),
                LockedTime = DatabaseHelper.SafeGetValue<DateTime?>(row, "LockedTime", null),
                LoginName = DatabaseHelper.SafeGetValue<string>(row, "LoginName", string.Empty),
                MustChangePassword = DatabaseHelper.SafeGetValue<bool>(row, "MustChangePassword", false),
                Password = DatabaseHelper.SafeGetValue<string>(row, "Password", string.Empty),
                Organization_ID = DatabaseHelper.SafeGetValue<Guid>(row, "Organization_ID", Guid.Empty),
            };

            //返回实体
            return entity;
        }

        public static User GetUserByID(Guid userID)
        {
            using (var context = new TalimuEntities())
            {
                return context.User.Include("UserRole").Include("Organization").FirstOrDefault(user => user.UserID == userID);
            }
        }

        public static List<User> GetUserList()
        {
            using (var context = new TalimuEntities())
            {
                return context.User.ToList();
            }
        }

        public static void DeleteUser(Guid userID)
        {
            using (var context = new TalimuEntities())
            {
                //Delete the User Role
                var roles = context.UserRole.Where(userRole => userRole.UserID == userID).ToList();
                foreach (var userRole in roles)
                {
                    context.CreateObjectSet<UserRole>().Attach(userRole);
                    context.ObjectStateManager.ChangeObjectState(userRole, EntityState.Deleted);
                }

                //Delete the User
                var user = new User { UserID = userID };
                context.CreateObjectSet<User>().Attach(user);
                context.ObjectStateManager.ChangeObjectState(user, EntityState.Deleted);

                context.SaveChanges();
            }
        }

        public static void ResetPassword(Guid userID)
        {
            //获得默认密码
            string defaultPassword = System.Configuration.ConfigurationManager.AppSettings["DefaultPassword"];

            //判断是否指定了默认密码
            if (string.IsNullOrEmpty(defaultPassword))
            {
                //设置为默认值
                defaultPassword = "123456";
            }

            using (TalimuEntities context = new TalimuEntities())
            {
                var target = context.User.FirstOrDefault(user => user.UserID == userID);

                if (target == null)
                    return;

                target.Password = PasswordHash.GetHashedPasswordBase64(defaultPassword);
                target.MustChangePassword = true;
                context.SaveChanges();
            }
        }

        public static void UpdateUser(AccountDetail data)
        {
            using (var context = new TalimuEntities())
            {
                var target = context.User.FirstOrDefault(user => user.UserID == data.UserID);
                if (target == null)
                    return;

                target.UserName = data.UserName;
                target.LoginName = data.LoginName;
                target.IsEnabled = data.IsEnabled;
                target.Organization_ID = data.OrganizationID;
                target.Memo = data.Memo;

                //Delete current role.
                var roles = context.UserRole.Where(userRole => userRole.UserID == data.UserID).ToList();
                foreach (var userRole in roles)
                {
                    context.CreateObjectSet<UserRole>().Attach(userRole);
                    context.ObjectStateManager.ChangeObjectState(userRole, EntityState.Deleted);
                }

                //Add new user role.
                var isSystemAdmin = Helper.CurrentPrincipal.IsInRole("SystemAdmin");
                foreach (var roleID in data.Roles)
                {
                    if (!isSystemAdmin && !Helper.CurrentPrincipal.RoleIDList.Contains(roleID))
                        continue; // the creator do not have the role.

                    var userRole = new UserRole();
                    userRole.UserRoleID = Guid.NewGuid();
                    userRole.UserID = data.UserID;
                    userRole.RoleID = roleID;
                    context.AddToUserRole(userRole);
                }
                context.SaveChanges();
            }
        }

        public static void CreateUser(AccountDetail data)
        {
            using (var context = new TalimuEntities())
            {
                var user = new User();

                //1. add the user.
                user.UserID = Guid.NewGuid();
                user.UserName = data.UserName;
                user.LoginName = data.LoginName;
                user.IsBuildin = data.IsBuildin;
                user.IsEnabled = data.IsEnabled;
                user.Organization_ID = data.OrganizationID;
                user.Memo = data.Memo;
                user.Password = PasswordHash.GetHashedPasswordBase64(data.Password);
                context.AddToUser(user);

                var isSystemAdmin = Helper.CurrentPrincipal.IsInRole("SystemAdmin");

                //2. add the role.
                if (data.Roles != null)
                {
                    foreach (var roleID in data.Roles)
                    {
                        if (!isSystemAdmin && !Helper.CurrentPrincipal.RoleIDList.Contains(roleID))
                            continue; // the creator do not have the role.

                        var userRole = new UserRole();
                        userRole.UserRoleID = Guid.NewGuid();
                        userRole.UserID = user.UserID;
                        userRole.RoleID = roleID;
                        context.AddToUserRole(userRole);
                    }
                }

                context.SaveChanges();
            }
        }

        /// <summary>
        /// 查询账户。
        /// </summary>
        /// <param name="query">查询信息。</param>
        /// <returns>账户信息。</returns>
        public static GridModel<AccountListRow> QueryUser(JosnPagingQueryModel query)
        {
            //打开数据上下文
            using (TalimuEntities context = new TalimuEntities())
            {
                //创建查询
                var result = UIHelper.GetGridModelFromQueryModel<WaterRegimenMonitor.Web.DataModel.User>
                    (
                        context.User.Include("Organization"),
                        query.page,
                        query.limit,
                        GetSortDescriptorFromQueryModel(query.SortModel),
                        GetSearchFilterFromQueryModel(query.FilterModel)
                    );

                //获得结果集
                var list = result.Data.Select(user => new AccountListRow()
                {
                    UserID = user.UserID,
                    UserName = user.UserName,
                    LoginName = user.LoginName,
                    IsBuildin = user.IsBuildin,
                    IsEnabled = user.IsEnabled,
                    LastLoginTime = user.LastLoginTime,
                    Organization = user.Organization.Organization_Name,
                    Memo = user.Memo
                }).ToList<AccountListRow>();

                //返回结果
                return new GridModel<AccountListRow>()
                {
                    Aggregates = result.Aggregates,
                    Data = list,
                    Total = result.Total
                };
            }
        }

        private static List<IFilterDescriptor> GetSearchFilterFromQueryModel(IEnumerable<JosnQueryFilterModel> filterModels)
        {
            var filterList = new List<IFilterDescriptor>();
            foreach (var item in filterModels)
            {
                filterList.Add(new FilterDescriptor(item.property, FilterOperator.Contains, item.value));
            }

            return filterList;
        }

        private static List<SortDescriptor> GetSortDescriptorFromQueryModel(IEnumerable<JosnQuerySortModel> sortModels)
        {
            //convert the sort description.
            var sortList = new List<SortDescriptor>();
            foreach (var item in sortModels)
            {
                sortList.Add(new SortDescriptor()
                {
                    Member = item.property,
                    SortDirection = item.direction.ToLower() == "desc" ? ListSortDirection.Descending : ListSortDirection.Ascending
                });
            }
            return sortList;
        }


        /// <summary>
        /// 用户登陆。
        /// </summary>
        /// <param name="user">要登陆的用信息。</param>
        public static void UserLastLogin(User user)
        {
            //判断实体是否有效
            if (null == user)
            {
                return;
            }

            //获得数据库对象
            Database db = DatabaseFactory.CreateDatabase();

            //创建命令
            SqlCommand command = new SqlCommand
            {
                CommandText = "UPDATE [User] SET [LastLoginTime] = @LastLoginTime WHERE [UserID] = @UserID",
                CommandType = System.Data.CommandType.Text
            };

            //创建参数
            SqlParameter paramUserID = new SqlParameter()
            {
                SqlDbType = System.Data.SqlDbType.UniqueIdentifier,
                ParameterName = "@UserID",
                Value = user.UserID
            };

            //创建参数
            SqlParameter paramPassword = new SqlParameter()
            {
                SqlDbType = System.Data.SqlDbType.DateTime,
                ParameterName = "@LastLoginTime",
                Value = DateTime.Now
            };

            //添加参数
            command.Parameters.Add(paramPassword);
            command.Parameters.Add(paramUserID);

            //执行脚本
            db.ExecuteNonQuery(command);
        }

        /// <summary>
        /// 更新密码。
        /// </summary>
        /// <param name="userID">用户编号。</param>
        /// <param name="password">新密码。</param>
        public static void ChangePassword(Guid userID, string password)
        {
            //获得数据库对象
            Database db = DatabaseFactory.CreateDatabase();

            //创建命令
            SqlCommand command = new SqlCommand
            {
                CommandText = "UPDATE [User] SET [Password] = @Password WHERE [UserID] = @UserID",
                CommandType = System.Data.CommandType.Text
            };

            //创建参数
            SqlParameter paramUserID = new SqlParameter()
            {
                SqlDbType = System.Data.SqlDbType.UniqueIdentifier,
                ParameterName = "@UserID",
                Value = userID
            };

            //创建参数
            SqlParameter paramPassword = new SqlParameter()
            {
                SqlDbType = System.Data.SqlDbType.NVarChar,
                ParameterName = "@Password",
                Value = password
            };

            //添加参数
            command.Parameters.Add(paramPassword);
            command.Parameters.Add(paramUserID);

            //执行脚本
            db.ExecuteNonQuery(command);
        }
    }
}